#!/usr/bin/python
import cherrypy
import csv
import time
import datetime
import json
import math
import httplib

class Route(object):
    @staticmethod
    def get_bus_position(route):
        conn = httplib.HTTPConnection("mc933.lab.ic.unicamp.br:8017")

        if (int(route) == 2):
            baseURI = '/onibus/1'
        elif (int(route) == 3):
            baseURI = '/onibus/0'
        else:
            baseURI = '/onibus/' + str(route)

        print("baseURI: " + baseURI)

        conn.request("GET", baseURI)
        r1 = conn.getresponse()
        data1 = r1.read()

        if (len(data1) <= 0):
            return None
        
        data1 = json.loads(data1)

        print("dados positron: " + str(data1))
        
        return data1

    @staticmethod
    def closest_segment(route, checkpoints, bus_long, bus_lati):
        closest_checkpoints = None
        min_dist = 100
        list_dist = []

        for count in range(1,len(checkpoints)):
            if (float(checkpoints[count-1]["long"]) == float(checkpoints[count]["long"]) or
                float(checkpoints[count-1]["lati"]) == float(checkpoints[count]["lati"])):
                continue
            
            dist = Route.dist_line_point(float(checkpoints[count-1]["long"]), float(checkpoints[count-1]["lati"]),
                                        float(checkpoints[count]["long"]),   float(checkpoints[count]["lati"]),
                                        bus_long, bus_lati)

            list_dist.append(dist)

            #print(str(dist) + ',' + checkpoints["checkpoints"][count-1]["id"])

            if (dist < min_dist):
                if (min_dist - dist > 0.000005):
                    min_dist = dist
                    closest_checkpoints = checkpoints[count-1]

        print("closest_segment - min_dist: " + str(min_dist))

        #Posicao do onibus muito longe de qualquer segmento
        if (min_dist > 0.001):
            return None
        
        return closest_checkpoints

    @staticmethod
    def dist_line_point(x1,y1, x2,y2, x3,y3):
        px = x2-x1
        py = y2-y1

        s = px*px + py*py

        u =  ((x3 - x1) * px + (y3 - y1) * py) / s

        if u > 1:
            u = 1
        elif u < 0:
            u = 0

        x = x1 + u * px
        y = y1 + u * py

        dx = x - x3
        dy = y - y3

        dist = math.sqrt(dx*dx + dy*dy)

        return dist

class Timer(object):
    def __init__(self):
        last_update = datetime.datetime.now()
        while(True):
            t_delta = datetime.datetime.now() - last_update
            delta_secs = (t_delta.microseconds + (t_delta.seconds + t_delta.days * 24 * 3600) * 10**6) / 10**6
            if (delta_secs > 60):
                stream_last = open('data/ultimo_checkpoint2.yml')
                last_check = json.load(stream_last)

                stream = open('data/checkpoints2.yml')
                checkpoints = json.load(stream)

                checkpoints_ordered = filter(lambda p: int(p["id"]) >= int(last_check["last_check"]), checkpoints["checkpoints"])+ filter(lambda p: int(p["id"]) < int(last_check["last_check"]), checkpoints["checkpoints"])

                bus_position = Route.get_bus_position("2")
                bus_server_time = bus_position["systemDatetime"]

                closest_check = Route.closest_segment("2", checkpoints_ordered, bus_position["longitude"], bus_position["latitude"]);

                FMT = '%Y-%m-%d %H:%M:%S'
                t_delta1 = datetime.datetime.now() - datetime.datetime.strptime(bus_server_time, FMT)
                delta_secs1 = (t_delta1.microseconds + (t_delta1.seconds + t_delta1.days * 24 * 3600) * 10**6) / 10**6

                file = open('data/ultimo_checkpoint2.yml', 'wb')

                if (False):
                    file.write(json.dumps({"last_check":"1", "lati":"", "long":"", "date":bus_position["systemDatetime"], "update_date":str(datetime.datetime.now())}))
                elif (closest_check != None):
                    file.write(json.dumps({"last_check":str(closest_check["id"]), "lati":bus_position["latitude"], "long":bus_position["longitude"], "date":bus_position["systemDatetime"], "update_date":str(datetime.datetime.now())}))
                else:
                    file.write(json.dumps({"last_check":"1", "lati":"", "long":"", "date":bus_position["systemDatetime"], "update_date":str(datetime.datetime.now())}))

                file.close()

                last_update = datetime.datetime.now()

timer = Timer()
